package com.boot.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.boot.common.constant.GlobalVar;
import com.boot.common.constant.MessageConstant;
import com.boot.common.constant.RedisConstant;
import com.boot.common.result.Result;
import com.boot.system.entity.SysConfig;
import com.boot.system.mapper.ConfigMapper;
import com.boot.system.service.ConfigService;
import com.boot.util.ConvertUtil;
import com.boot.util.RedisUtil;
import com.boot.util.SecurityUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统配置服务实现类
 */
@Slf4j
@RequiredArgsConstructor
@Service("configService")
public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, SysConfig> implements ConfigService {

    private final RedisUtil redisUtil;

    /**
     * 系统启动完成后，加载系统配置到缓存
     */
    @PostConstruct
    public void initConfig() {
        List<SysConfig> list = this.getConfigList(new HashMap<>());
        for (SysConfig sysConfig : list){
            String key = StrUtil.format(RedisConstant.Config.INFO, sysConfig.getId(), sysConfig.getKey());
            redisUtil.set(key, sysConfig);
        }
        log.info("系统配置加载完成！");
    }

    @Override
    public Page<SysConfig> getConfigPage(Map<String, Object> queryParam) {
        // 基础参数
        int pageNum = (int) queryParam.getOrDefault("pageNum", 1);
        int pageSize = (int) queryParam.getOrDefault("pageSize", 10);
        // 查询条件
        QueryWrapper query = QueryWrapper.create().from(SysConfig.class);
        // 模糊查询
        query.and(q -> q.and(SysConfig::getName).like(queryParam.get("keywords"))
                        .or(SysConfig::getKey).like(queryParam.get("keywords"))
                        .or(SysConfig::getRemark).like(queryParam.get("keywords")),
                ObjectUtil.isNotEmpty(queryParam.get("keywords")));
        if (ObjectUtil.isNotEmpty(queryParam.get("status"))) {
            // 状态
            query.eq("status", queryParam.get("status"));
        }
        query.orderBy((String) queryParam.getOrDefault("orderBy", "update_time desc, id desc"));
        return this.page(new Page<>(pageNum, pageSize), query);
    }

    @Override
    public List<SysConfig> getConfigList(Map<String, Object> queryParam) {
        // 查询条件
        QueryWrapper query = QueryWrapper.create().from(SysConfig.class);
        // 模糊查询
        query.and(q -> q.and(SysConfig::getName).like(queryParam.get("keywords"))
                        .or(SysConfig::getKey).like(queryParam.get("keywords"))
                        .or(SysConfig::getRemark).like(queryParam.get("keywords")),
                ObjectUtil.isNotEmpty(queryParam.get("keywords")));
        if (ObjectUtil.isNotEmpty(queryParam.get("status"))) {
            // 状态
            query.eq("status", queryParam.get("status"));
        }
        query.orderBy((String) queryParam.getOrDefault("orderBy", "id desc"));
        return this.list(query);
    }

    @Override
    public Result<?> addConfig(Map<String, Object> dataParam) {
        //判断是否已存在
        if (dataParam.get("key") != null) {
            SysConfig sysConfigTemp = this.mapper.selectByConfigKey((String) dataParam.get("key"));
            if (sysConfigTemp != null) {
                //已存在
                return Result.error(MessageConstant.CONFIG_EXIST);
            }
        }
        SysConfig sysConfig = ConvertUtil.mapToClass(dataParam, SysConfig.class);
        sysConfig.setCreateBy(SecurityUtil.getUid());
        sysConfig.setCreateTime(GlobalVar.systemTime);
        sysConfig.setUpdateBy(SecurityUtil.getUid());
        sysConfig.setUpdateTime(GlobalVar.systemTime);
        boolean result = this.save(sysConfig);
        if (result) {
            //设置缓存
            this.setCache(sysConfig.getId());
        }
        return Result.success(result);
    }

    @Override
    public Result<?> updateConfig(Map<String, Object> dataParam) {
        //查询原数据
        SysConfig oldSysRole = this.getById(Long.valueOf(dataParam.get("id").toString()));
        //判断Key是否可以修改
        if (dataParam.get("key") != null && !dataParam.get("key").equals(oldSysRole.getKey())) {
            SysConfig sysConfigTemp = this.mapper.selectByConfigKey((String) dataParam.get("key"));
            if (sysConfigTemp != null) {
                //已存在
                return Result.error(MessageConstant.CONFIG_EXIST);
            }
        }
        SysConfig sysConfig = ConvertUtil.mapToClass(dataParam, SysConfig.class);
        sysConfig.setUpdateBy(SecurityUtil.getUid());
        sysConfig.setUpdateTime(GlobalVar.systemTime);
        boolean result = this.updateById(sysConfig);
        if (result) {
            //更新缓存
            this.deleteCache(Collections.singletonList(sysConfig.getId()));
            this.setCache(sysConfig.getId());
        }
        return Result.success(result);
    }

    @Override
    public boolean deleteConfig(String ids) {
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .collect(Collectors.toList());
        //先删除缓存
        this.deleteCache(idList);
        //数据库-逻辑删除
        return this.removeByIds(idList);
    }

    @Override
    public Map<String, String> getCacheList() {
        String prefix = StrUtil.format(RedisConstant.Config.INFO, "*", "*");
        Set<String> keys = redisUtil.getKeys(prefix);
        Map<String, String> map = new HashMap<>();
        for (String key : keys) {
            //获取缓存
            SysConfig sysConfig = (SysConfig) redisUtil.get(key);
            if (sysConfig != null && sysConfig.getStatus() == 0){
                map.put(sysConfig.getKey(), sysConfig.getValue());
            }
        }
        return map;
    }

    @Override
    public Object getCache(String configKey) {
        String prefix = StrUtil.format(RedisConstant.Config.INFO, "*", configKey);
        //获取真实的缓存Key
        String key = null;
        Set<String> keys = redisUtil.getKeys(prefix);
        for (String item : keys) {
            key = item;
        }
        if (key != null) {
            SysConfig sysConfig = (SysConfig) redisUtil.get(key);
            return sysConfig.getValue();
        }
        return null;
    }

    @Override
    public void setCache(Long id) {
        SysConfig sysConfig = this.getById(id);
        if (sysConfig != null){
            String key = StrUtil.format(RedisConstant.Config.INFO, sysConfig.getId(), sysConfig.getKey());
            redisUtil.set(key, sysConfig);
        }
    }

    @Override
    public void deleteCache(List<Long> ids) {
        for (Long id : ids){
            String prefix = StrUtil.format(RedisConstant.Config.INFO, id, "*");
            //获取真实的缓存Key
            String key = null;
            Set<String> keys = redisUtil.getKeys(prefix);
            for (String item : keys) {
                key = item;
            }
            if (key != null) {
                //删除
                redisUtil.delete(key);
            }
        }
    }
}
